using System;
using System.Collections.Generic;
using System.Text;

namespace RapidHDL
{
    public class PacketBlock
    {
        public Packet[] Packets;
        int iIndex;

        public void InitPackets()
        {
            for (int iIdx = 0; iIdx < Packets.Length; iIdx++)
            {
                Packets[iIdx] = new Packet();
            }
        }

        public PacketBlock(int piLength)
        {
            Packets = new Packet[piLength];
            InitPackets();
            iIndex = 0;
        }

        public PacketBlock()
        {
            Packets = new Packet[128];
            InitPackets();
            iIndex = 0;
        }

        public void Reset()
        {
            iIndex = 0;
        }

        public void AddPacket(uint piRoute, uint piData)
        {
            Packets[iIndex].Route = piRoute;
            Packets[iIndex].Data = piData;
            iIndex++;
        }

        public int PacketCount
        {
            get { return iIndex; }
        }

        public ushort[] ToArray()
        {
            ushort[] stream = new ushort[iIndex * 4];
            ushort iHigh = 0;
            ushort iLow = 0;

            int iOutIdx = 0;
            for (int iIdx = 0; iIdx < iIndex; iIdx++)
            {
                Packet oPacket = Packets[iIdx];
                Conversion.UIntToShorts(oPacket.Data, ref iHigh, ref iLow);
                stream[iOutIdx] = iLow;
                stream[iOutIdx + 1] = iHigh;
                //System.Windows.Forms.MessageBox.Show(Conversion.IntToBinaryString((int)oPacket.Route, 32));
                Conversion.UIntToShorts(oPacket.Route, ref iHigh, ref iLow);
                stream[iOutIdx + 2] =  iLow;
                stream[iOutIdx + 3] = iHigh;
                iOutIdx += 4;
            }
            return stream;
        }

        public int FromArray(ref ushort[] paStream, int piLength)
        {
            int iLastPacket = 0;
            int iPacket = -1;
            uint iData = 0;
            uint iRoute = 0;

            int iAIdx=0;
            int iBIdx=0;

            Reset();

            //int iPacketCount = 0;

            for (int iIdx = 0; iIdx < piLength; iIdx++)
            {
                iPacket = PacketId(paStream[iIdx]);
                //Console.WriteLine(iPacket.ToString() + " - " + paStream[iIdx].ToString());
                if (iPacket != 0)
                {
                    //iPacketCount++;
                    if (iPacket == iLastPacket + 1)
                    {
                        if (iPacket == 3)
                        {
                            ushort uLow = paStream[iAIdx];
                            ushort uMid = paStream[iBIdx];
                            ushort uHigh = paStream[iIdx];

                            iData = (uint)((uHigh & 0x000F) << 28) | (uint)((uMid & 0x3FFF) << 14) | (uint)(uLow & 0x3FFF);
                            iRoute = (uint)((uHigh & 0x3FF0) >> 4);
                            AddPacket(iRoute, iData);
                            iLastPacket = 0;
                        }
                        else
                        {
                            if (iPacket == 1)
                                iAIdx = iIdx;
                            else
                                iBIdx = iIdx;

                            iLastPacket = iPacket;
                        }
                    }
                    else
                    {
                       //System.Windows.Forms.MessageBox.Show("Packet out of order " + iLastPacket.ToString() + " to " + iPacket.ToString());
                       iLastPacket = 0;
                   }
                }
            }

            //if (iPacketCount != 24)
                //Console.WriteLine(iPacketCount.ToString());

            
            //System.Windows.Forms.MessageBox.Show("Packets - " + iPacketCount.ToString());
            if (iLastPacket == 1 || iLastPacket == 2)
                return iAIdx;
            return -1;
        }

        private int PacketId(ushort psValue)
        {
            return (psValue & 0xC000) >> 14;
        }

    }
}
